package Day_0214.JVM;

/**
 * @author zxc
 * @date 2023/02/14 23:08
 **/
public class JVM_RunTime_Data_Area {
    public static void main(String[] args) {
        /**
         * 谈一谈对于JVM运行时数据区的理解
         * ===》
         * Java 虚拟机所管理的内存（运行时数据区，RunTime data area）被划分为如下几个区域：
         * 1.程序计数器（Program Counter Register）：
         * （1）当前线程所执行字节码的行号指示器，字节码解析器的工作是通过改变这个计数器的值，
         *  来选取下一条需要执行的字节码指令，分支、循环、跳转、异常处理、线程恢复等基础功能，都需要依赖这个计数器来完成；
         * （2）在任何时刻，一个处理器内核只能运行一个线程，多线程是通过线程轮流切换，分配时间来完成的，
         *  即，需要程序计数器，来记住每个线程当前执行的位置，
         * （3）程序计数器是线程私有的，每个线程都已自己的程序计数器。
         *
         * 2.Java 虚拟机栈（Java Virtual Machine Stacks）：
         * （1）用于存储局部变量表、操作数栈、动态链接、方法出口等信息；
         * （2）虚拟机栈是线程私有的，随线程生灭。虚拟机栈描述的是线程中的方法的内存模型：
         * （3）每个方法被执行的时候，都会在虚拟机栈中同步创建一个栈帧（stack frame）;方法被执行时入栈，执行完后出栈
         *  每个栈帧的包含如下的内容
         *  a.局部变量表:
         *  局部变量表中存储着方法里的java基本数据类型（byte/boolean/char/int/long/double/float/short）以及对象的引用
         *  （注：这里的基本数据类型指的是方法内的局部变量）
         *  b.操作数栈
         *  c.动态连接
         *  d.方法返回地址
         *
         * （4）虚拟机栈可能会抛出两种异常：
         *  a.如果线程请求的栈深度大于虚拟机所规定的栈深度，则会抛出StackOverFlowError即栈溢出
         *  b.如果虚拟机的栈容量可以动态扩展，那么当虚拟机栈申请不到内存时，会抛出OutOfMemoryError，即，OOM内存溢出
         *
         * （5）产生StackOverFlowError的原因是：
         *  无限递归循环调用（最常见）。
         *  执行了大量方法，导致线程栈空间耗尽。
         *  方法内声明了海量的局部变量。
         *
         * 3.本地方法栈（Native Method Stack）：
         * （1）与虚拟机栈的作用是一样的，只不过虚拟机栈是服务 Java方法的，而本地方法栈是为虚拟机调用 Native 方法服务的；
         * （2）本地方法栈与虚拟机栈的作用是相似的,都会抛出OutOfMemoryError和StackOverFlowError，都是线程私有的;
         * （3）主要的区别在于：
         *  a.虚拟机栈执行的是java方法
         *  b.本地方法栈执行的是native方法
         *
         * 4.Java 堆（Java Heap）：
         * 1）java堆是JVM内存中最大的一块，由所有线程共享, 是由垃圾收集器管理的内存区域，主要存放对象实例;
         *
         * （2）对象实例
         *  类初始化生成的对象;
         *  基本数据类型的数组,也是对象实例;
         *
         * （3）字符串常量池
         *  字符串常量池原本存放于方法区，从jdk7开始放置于堆中;
         *  字符串常量池存储的是string对象的直接引用，而不是直接存放的对象，是一张string table;
         *  ===> 即，字符串常量池所存储的是，String对象的直接引用;
         *
         * （4）静态变量
         *  静态变量是有static修饰的变量，jdk7时从方法区迁移至堆中;
         *
         * （5）线程分配缓冲区（Thread Local Allocation Buffer）
         *  线程私有，但是不影响java堆的共性;
         *  增加线程分配缓冲区是为了提升对象分配时的效率;
         *
         * 2）java堆既可以是固定大小的，也可以是可扩展的（通过参数-Xmx和-Xms设定），如果堆无法扩展或者无法分配内存时也会报OOM
         *
         * 5.方法区（Methed Area）：
         * 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
         *
         */
    }
}
